home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint104s.zoo
/
mint.src
/
intr.spp
< prev
next >
Wrap
Text File
|
1993-03-08
|
13KB
|
477 lines
; Copyright 1992 Eric R. Smith
; All rights reserved.
%include "magic.i"
;
; interrupt wrapping routines; these should just save registers and call
; the appropriate C handlers, unless speed is a major problem
;
TEXT
;
; first, utilities for setting processor status level
;
XDEF _spl7,_spl
_spl7:
move.w sr,d0
ori.w #$0700,sr
rts
_spl:
move.w 4(sp),d0
move.w d0,sr
rts
XDEF _mint_5ms
XDEF _mint_timer
XDEF _mint_vbl
XREF _timeout ; C time routine
XREF _old_timer ; old GEMDOS time vector
XREF _old_vbl ; old GEMDOS vbl vector
XREF _old_5ms
XREF _build_context
XREF _restore_context
XREF _proc_clock ; controls process' allocation of CPU time
XREF _curproc
XREF _enter_kernel
XREF _leave_kernel
XREF _preempt
XREF _in_kernel
; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
_mint_5ms:
move.l a0,-(sp)
move.l _curproc,a0
tst.w _in_kernel
bne.s L_systime
lea P_USRTIME(a0),a0 ; get offset to curproc->usrtime
addq.l #5,(a0) ; update the time
move.l (sp)+,a0
move.l _old_5ms+8,-(sp) ; branch to old vector
rts
L_systime:
lea P_SYSTIME(a0),a0 ; get offset to curproc->systime
addq.l #5,(a0)
move.l (sp)+,a0
move.l _old_5ms+8,-(sp)
rts
_mint_timer:
movem.l d0-d2/a0-a2,-(sp) ; save C registers
jsr _timeout
movem.l (sp)+,d0-d2/a0-a2
move.l _old_timer+8,-(sp) ; jump to GEMDOS time vector
rts
_mint_vbl:
%ifndef ONLY030
tst.w ($59e).w ; test longframe (AKP)
beq.s L_short1
%endif
clr.w -(sp) ; yes, long frames: push a frame word
L_short1:
pea L_comeback ; push fake PC
move.w sr,-(sp) ; push status register
move.l _old_vbl+8,-(sp) ; go service the interrupt
rts
L_comeback:
tst.w _proc_clock ; has time expired yet?
beq.s L_expired ; yes -- maybe go switch processes
L_out:
rte ; no -- just return
L_expired:
btst #5,(sp) ; user mode?
bne.s L_out ; no -- switching is not possible
tst.w ($43e).w ; test floppy disk lock variable
bne.s L_out ; if locked, can't switch
tst.w _in_kernel ; are we doing a kernel operation?
bne.s L_out
L_switch:
clr.w -(sp) ; no frame format needed
move.l _curproc,-(sp)
addq.l #P_CTXT0,(sp) ; to get &curproc->ctxt[SYSCALL]
jsr _build_context ; build context
move.l _curproc,a0
move.l (a0),sp ; use curproc->sysstack
jsr _enter_kernel ; enter kernel
jsr _preempt ; yield processor
ori.w #$700,sr ; spl7()
jsr _leave_kernel ; restore vectors
move.l _curproc,a0
pea 4(a0)
jsr _restore_context ; back to user
;
; reset routine -- called on a warm boot. Note that TOS sends the
; address to which we should return in register a6. Also note that
; the stack pointer is in an unknown state, so we set up our own
;
XDEF _reset
XREF _init_tail ; see main.c
XREF _restr_intr
_reset:
move.w #$2700,sr ; avoid interruption here
move.l sp,_init_tail ; save A7
lea _init_tail,sp ; set up temporary stack
lea 256(sp),sp
movem.l d0-d2/a0-a2,-(sp) ; save C registers
jsr _restr_intr ; restore interrupts
movem.l (sp)+,d0-d2/a0-a2 ; restore registers
move.l _init_tail,sp
jmp (a6) ; reset again
;
; routine for doing a reboot
;
XDEF _reboot
_reboot:
move.w #$2700,sr ; avoid interrupts
move.l (0).w,sp ; get sp after reboot
move.l (4).w,a6 ; get new reboot address
jmp _reset
;
; routine for mouse packet handling
;
XDEF _newmvec
XDEF _newjvec
XREF _mouse_handler
; Experimental three button mouse support (by jr@ms.maus.de,
; August 4, 1992
;
; Should work with the mice shipped with Atari's ASV or
; compatible ones (like Golden Image GI-6000). Might not work
; on ST/STE systems with older IKBD's or keyboards. The middle mouse
; button is wired to one of the joystick directions on joystick one.
;
; _newmvec is the same as before with two exceptions:
; 1. the first byte of the packet is saved for the joystick handler
; 2. the bit for the middle mouse button is ored in
;
; _newjvec hooks into the joystick vector and chains to the normal
; handler. The middle mouse button state is saved in a special
; register for _newmvec, and a 'fake' mouse packet is set up
; (by merging the last mouse packet header, or-ing in the
; middle button state and using 0/0 for the x/y increment).
;
; the faked_packet and third_button variables are declared at the
; end of this file
_newmvec:
move.l a0,-(sp)
move.b (a0),d0
move.b d0,faked_packet
or.b third_button,d0
move.b d0,(a0)
jsr _mouse_handler
move.l (sp)+,a0
rts
;
; routine for joystick packet handling (used for three button mice)
;
XDEF _newjvec
XREF _oldjvec
_newjvec:
move.l a0,-(sp) ; save a0 on the stack
move.b 2(a0),d0 ; joystick direction
and.b #1,d0 ; middle mouse button in lowest bit
add.b d0,d0 ; times 4
add.b d0,d0
move.b d0,third_button ; save it for use in newmvec
lea faked_packet,a0 ; 'our' faked mouse event
move.b (a0),d0
and.b #$3,d0 ; unmask our mouse button
or.b #$F8,d0 ; or in correct header
or.b third_button,d0 ; or in the current status
move.b d0,(a0) ; write it back
move.l a0,-(sp) ; pass pointer to fake packet
jsr _mouse_handler ; to \dev\mouse handler
addq.l #4,sp ; pop parameter
move.l (sp)+,a0 ; restore original a0 value
move.l _oldjvec,-(sp) ; jump to original joystick handler
rts
;
; new ikbd keyboard interrupt vector
; kintr is a global variable that should be non-zero if a keyboard
; event occured
;
XDEF _new_ikbd
XREF _old_ikbd
XREF _kintr
_new_ikbd:
move.w #1,_kintr
move.l _old_ikbd+8,-(sp)
rts ; jump to system interrupt routine
;
; simple signal handlers
; global variables referenced:
; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
; sig_routine: (signal.c): pointer to which signal catching routine to
; call (e.g. for SIGBUS, or whatever)
;
XDEF _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv,_new_linef
XDEF _new_trace,_new_chk,_new_trapv,_new_fpcp,_new_mmu,_new_pmmuacc
XDEF _new_uninit,_new_spurious,_new_format,_new_cpv
XREF _in_kernel,_sig_routine
XREF _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
XREF _haltformat,_haltcpv
XREF _sig_exc
;
; New bus error handler for memory protection: get the ssp and
; put it in the proc structure before calling
; _sigbus. When the bus error happens in the kernel we don't save
; any contexts.
; We don't want to mess up any registers here because we might bring the
; page in and RTE.
;
_new_bus:
move.w #$8,_sig_exc
move.l #_mmu_sigbus,_sig_routine
Do_sig:
move.l a0,-(sp) ; save a0
move.l _curproc,a0
move.l sp,P_EXCSSP(a0)
addq.l #4,P_EXCSSP(a0)
move.l 6(sp),P_EXCPC(a0)
move.l (sp)+,a0
tst.w _in_kernel ; are we already in the kernel?
bne.s Kernel ; yes
move.w _sig_exc,-(sp)
move.l _curproc,-(sp)
addq.l #4,(sp) ; push offset of save area
jsr _build_context
move.l _curproc,a4
move.l (a4),sp ; put us in the system stack
jsr _enter_kernel ; set up kernel vectors
move.l _sig_routine,a1 ; get signal handling routine
jsr (a1) ; go do it
ori.w #$0700,sr ; spl7()
jsr _leave_kernel ; leave kernel
addq.w #4,a4 ; get context save area address
move.l a4,-(sp) ; push it
jsr _restore_context ; restore the context
;
; here's what we do if we already were in the kernel
;
Kernel:
movem.l d0-d2/a0-a2,-(sp) ; save reggies
move.l _sig_routine,a1 ; get handler
jsr (a1) ; go do it
movem.l (sp)+,d0-d2/a0-a2
rte
;
; _mmu_sigbus: a pre-handler for _sigbus. Check the reason for the bus
; error and report if it was a real access fault.
;
_mmu_sigbus:
move.l a2,-(sp)
move.l _curproc,a0
move.l P_EXCSSP(a0),a1 ; a1 is now exception_ssp
move.w $A(a1),d0 ; d0 is SSR
move.l $10(a1),a1 ; a1 is the access address
move.l a1,P_EXCADDR(a0) ; save the access address
ptestr d0,(a1),#7,a2 ; a2 is the table address
move.l a2,P_EXCTBL(a0) ; save table address in curproc
pmove mmusr,P_EXCMMUSR(a0) ; save resulting mmusr in curproc
move.l (sp)+,a2
jmp _sigbus ; chain to bus-error handler
_new_addr:
move.w #$c,_sig